﻿// CustomFolderPicker.cpp: 实现文件
//
#include "afxdialogex.h"
#include "CustomFolderPickerDlg.h"
#include "../winapp/resource.h"
// CustomFolderPicker 对话框

IMPLEMENT_DYNAMIC(CCustomFolderPickerDialog, CDialogEx)

CCustomFolderPickerDialog::CCustomFolderPickerDialog(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_CUSTOMFOLDERPICKER, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

CCustomFolderPickerDialog::~CCustomFolderPickerDialog()
{
}

void CCustomFolderPickerDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_FOLDER_TREE, m_FolderTree);
}


BEGIN_MESSAGE_MAP(CCustomFolderPickerDialog, CDialogEx)
	ON_BN_CLICKED(IDOK, &CCustomFolderPickerDialog::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CCustomFolderPickerDialog::OnBnClickedCancel)
	ON_NOTIFY(TVN_ITEMEXPANDING, IDC_FOLDER_TREE, &CCustomFolderPickerDialog::OnTvnItemExpandingFolderTree)
	/*ON_NOTIFY(NM_DBLCLK, IDC_FOLDER_TREE, &CCustomFolderPickerDialog::OnNMDblclkFolderTree)*/
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_NOTIFY(TVN_ITEMCHANGED, IDC_FOLDER_TREE, &CCustomFolderPickerDialog::OnTvnItemChangedFolderTree)
END_MESSAGE_MAP()


// CustomFolderPicker 消息处理程序


void CCustomFolderPickerDialog::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	m_selectedPaths = GetSelectedPaths();
	CDialogEx::OnOK();
}


void CCustomFolderPickerDialog::OnBnClickedCancel()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialogEx::OnCancel();
}


BOOL CCustomFolderPickerDialog::OnInitDialog()
{
	CDialogEx::OnInitDialog();


	// TODO: 在此处添加消息处理程序代码
	auto nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
	auto nScreenHeight = GetSystemMetrics(SM_CYSCREEN);

	// Calculate the new size and position of the window
	auto nWindowWidth = nScreenWidth * 0.15;
	auto nWindowHeight = nScreenHeight * 0.3;
	auto nWindowLeft = (nScreenWidth - nWindowWidth) / 2;
	auto nWindowTop = (nScreenHeight - nWindowHeight) / 2;

	// Set the size and position of the window
	SetWindowPos(NULL, nWindowLeft, nWindowTop, nWindowWidth, nWindowHeight, SWP_NOZORDER | SWP_NOACTIVATE);
	
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	// 初始化树状视图控件
	//m_FolderTree.Attach(GetDlgItem(IDC_FOLDER_TREE)->m_hWnd);

	// 添加驱动器
	AddDrivesToTree();

	// 在这里根据需要添加其他节点和子节点
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

void CCustomFolderPickerDialog::AddDrivesToTree()
{
	TCHAR szDriveStrings[512];
	GetLogicalDriveStrings(sizeof(szDriveStrings), szDriveStrings);

	for (TCHAR* pszDrive = szDriveStrings; *pszDrive; pszDrive += _tcslen(pszDrive) + 1)
	{
		UINT driveType = GetDriveType(pszDrive);
		if (driveType != DRIVE_NO_ROOT_DIR)
		{
			CString str = pszDrive;
			if (!str.IsEmpty() && str.GetAt(str.GetLength() - 1) == _T('\\'))
			{
				str.Delete(str.GetLength() - 1);
			}
			HTREEITEM hDriveItem = m_FolderTree.InsertItem(str);
			m_FolderTree.SetItemData(hDriveItem, 0);
			m_FolderTree.InsertItem(_T("<Dummy>"), hDriveItem);
		}
	}
}

void CCustomFolderPickerDialog::AddSubFoldersToTree(HTREEITEM hParent, const CString& currentPath)
{
	CFileFind finder;
	BOOL bWorking = finder.FindFile(currentPath + _T("\\*"));

	while (bWorking)
	{
		bWorking = finder.FindNextFile();
		if (finder.IsDots())
		{
			continue;
		}

		if (finder.IsDirectory())
		{
			CString folderName = finder.GetFileName();
			HTREEITEM hItem = m_FolderTree.InsertItem(folderName, hParent);

			// 检查此文件夹是否有子文件夹
			CFileFind subFinder;
			BOOL bSubWorking = subFinder.FindFile(currentPath + _T("\\") + folderName + _T("\\*"));
			bool hasSubFolder = false;
			while (bSubWorking)
			{
				bSubWorking = subFinder.FindNextFile();
				if (subFinder.IsDots())
				{
					continue;
				}

				if (subFinder.IsDirectory())
				{
					hasSubFolder = true;
					break;
				}
			}

			if (hasSubFolder)
			{
				// 添加虚拟子节点，以便树控件为此节点显示 + 标志
				m_FolderTree.InsertItem(_T(""), hItem);
			}
		}
	}
}



void CCustomFolderPickerDialog::OnTvnItemExpandingFolderTree(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMTREEVIEW pTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

	// 检查是否是展开操作
	if (pTreeView->action == TVE_EXPAND)
	{
		HTREEITEM hItemExpanding = pTreeView->itemNew.hItem;

		// 获取当前选择的路径
		CString currentPath;
		HTREEITEM hCurrentItem = hItemExpanding;
		while (hCurrentItem)
		{
			CString strSeparator = (currentPath.IsEmpty() ? _T("") : _T("\\"));
			currentPath = m_FolderTree.GetItemText(hCurrentItem) + strSeparator + currentPath;
			hCurrentItem = m_FolderTree.GetParentItem(hCurrentItem);
		}

		// 检查是否是第一次展开
		if (m_FolderTree.GetItemData(hItemExpanding) == 0)
		{
			m_FolderTree.SetRedraw(FALSE); // 禁用重绘以提高性能

			// 删除虚拟子节点
			HTREEITEM hChildItem = m_FolderTree.GetChildItem(hItemExpanding);
			if (hChildItem)
			{
				m_FolderTree.DeleteItem(hChildItem);
			}

			// 添加子文件夹
			AddSubFoldersToTree(hItemExpanding, currentPath);

			// 标记为已展开过
			m_FolderTree.SetItemData(hItemExpanding, 1);

			m_FolderTree.SetRedraw(TRUE); // 重新启用重绘
		}
	}

	*pResult = 0;
}


//void CCustomFolderPickerDialog::OnNMDblclkFolderTree(NMHDR* pNMHDR, LRESULT* pResult)
//{
//	// 获取当前选中的项目
//	HTREEITEM hSelectedItem = m_FolderTree.GetSelectedItem();
//	if (hSelectedItem)
//	{
//		// 如果选中的项目已展开，则折叠它；否则展开它
//		if (m_FolderTree.GetItemState(hSelectedItem, TVIS_EXPANDED) & TVIS_EXPANDED)
//		{
//			m_FolderTree.Expand(hSelectedItem, TVE_COLLAPSE);
//		}
//		else
//		{
//			m_FolderTree.Expand(hSelectedItem, TVE_EXPAND);
//		}
//	}
//
//	*pResult = 0;
//}


void CCustomFolderPickerDialog::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
	
	CWnd* pOkButton = GetDlgItem(IDOK);
	CWnd* pCancelButton = GetDlgItem(IDCANCEL);
	if (pOkButton && pCancelButton)
	{
		auto nWidth = cx * 0.3;
		auto nHeight = cy * 0.1;
		auto nLeft = cx * 0.1;
		auto nTop = cy * 0.85;

		// Set the size and position of the button
		pOkButton->SetWindowPos(NULL, nLeft, nTop, nWidth, nHeight, SWP_NOZORDER | SWP_NOACTIVATE);

		nWidth = cx * 0.3;
		nHeight = cy * 0.1;
		nLeft = cx * 0.6;
		nTop = cy * 0.85;
		pCancelButton->SetWindowPos(NULL, nLeft, nTop, nWidth, nHeight, SWP_NOZORDER | SWP_NOACTIVATE);
	}
	// TODO: 在此处添加消息处理程序代码
	if (m_FolderTree.m_hWnd)
	{
		auto nWidth = cx *0.9;
		auto nHeight = cy * 0.8;
		auto nLeft = cx *0.05 ;
		auto nTop = 0;
		m_FolderTree.SetWindowPos(NULL, nLeft, nTop, nWidth, nHeight, SWP_NOZORDER | SWP_NOACTIVATE);
	}
}


void CCustomFolderPickerDialog::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	// 不为绘图消息调用 CDialogEx::OnPaint()
	// 使图标在工作区矩形中居中
	//SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
	//int cxIcon = GetSystemMetrics(SM_CXICON);
	//int cyIcon = GetSystemMetrics(SM_CYICON);
	//CRect rect;
	//GetClientRect(&rect);
	//int x = (rect.Width() - cxIcon + 1) / 2;
	//int y = (rect.Height() - cyIcon + 1) / 2;

	//// 绘制图标
	//dc.DrawIcon(x, y, m_hIcon);
}

void CCustomFolderPickerDialog::AddSelectedPaths(HTREEITEM hItem, CString currentPath, std::vector<CString>& selectedPaths) const
{
	while (hItem)
	{
		CString itemText = m_FolderTree.GetItemText(hItem);
		CString newPath = currentPath.IsEmpty() ? itemText : (currentPath + _T("\\") + itemText);

		if (m_FolderTree.GetCheck(hItem))
		{
			selectedPaths.push_back(newPath);
		}
		else
		{
			HTREEITEM hChildItem = m_FolderTree.GetChildItem(hItem);
			if (hChildItem)
			{
				AddSelectedPaths(hChildItem, newPath, selectedPaths);
			}
		}
		hItem = m_FolderTree.GetNextSiblingItem(hItem);
	}
}


std::vector<CString> CCustomFolderPickerDialog::GetSelectedPaths() const
{
	std::vector<CString> selectedPaths;
	HTREEITEM hRootItem = m_FolderTree.GetRootItem();
	AddSelectedPaths(hRootItem, _T(""), selectedPaths);
	return selectedPaths;
}

void CCustomFolderPickerDialog::OnTvnItemChangedFolderTree(NMHDR* pNMHDR, LRESULT* pResult)
{
	// 检查通知代码是否为 TVN_ITEMCHANGED
	NMTVITEMCHANGE* pTreeView = reinterpret_cast<NMTVITEMCHANGE*>(pNMHDR);

	// 检查复选框状态是否已更改
	if (pTreeView->uStateNew != (pTreeView->uStateOld))
	{
		HTREEITEM hItem = pTreeView->hItem;

		m_FolderTree.SelectItem(hItem);
	}
	*pResult = 0;
}
